package com.hunttown.mes.manage.controller._erp;

import com.hunttown.mes.common.keys.KeyConstants;
import com.hunttown.mes.common.OperateCode;
import com.hunttown.mes.manage.controller.common.AdminBaseClass;
import com.hunttown.mes.manage.controller.common.ModelService;
import com.hunttown.mes.rpc.domain.*;
import com.hunttown.mes.rpc.domain.enums.expense.BXTypeEnum;
import com.hunttown.mes.rpc.domain.enums.expense.BXStatusEnum;
import com.hunttown.mes.rpc.domain.enums.pay.ReceiveWayEnum;
import com.hunttown.common.domain.Page;
import com.hunttown.mes.common.utils.*;
import com.hunttown.mes.manage.service.*;
import com.hunttown.mes.rpc.domain.query.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

import static com.hunttown.mes.common.utils.PageUtils.PagePackage;

/**
 * @title: 报销
 * @author: wangjunfu
 * @date: 2019-07-07 10:50:24
 * @description:
 */
@Controller
@RequestMapping(value = "/erp/expense")
public class ExpenseController {

    private final static Logger logger = LoggerFactory.getLogger(ExpenseController.class);

    private final AnalysisManageManageService manageService;
    private final AnalysisCatalogManageService catalogService;
    private final TransportExpenseManageService expenseService;
    private final TransportExpenseDetailManageService expenseDetailService;
    private final TransactionService transactionService;
    private final TransportOperateLogManageService logService;
    private final TransportPurchaseDetailManageService purchaseDetailService;
    private final WorkflowApplyLineManageService applyLineService;
    private final WorkflowBusinessManageService businessService;
    private final WorkflowBusinessNodeManageService businessNodeService;
    private final WorkflowApplyManageService applyService;
    private final ModelService modelService;

    @Autowired
    public ExpenseController(AnalysisManageManageService manageService, AnalysisCatalogManageService catalogService, TransportExpenseManageService expenseService, TransportExpenseDetailManageService expenseDetailService, TransactionService transactionService, TransportOperateLogManageService logService, TransportPurchaseDetailManageService purchaseDetailService, WorkflowApplyLineManageService applyLineService, WorkflowBusinessManageService businessService, WorkflowBusinessNodeManageService businessNodeService, WorkflowApplyManageService applyService, ModelService modelService) {
        this.manageService = manageService;
        this.catalogService = catalogService;
        this.expenseService = expenseService;
        this.expenseDetailService = expenseDetailService;
        this.transactionService = transactionService;
        this.logService = logService;
        this.purchaseDetailService = purchaseDetailService;
        this.applyLineService = applyLineService;
        this.businessService = businessService;
        this.businessNodeService = businessNodeService;
        this.applyService = applyService;
        this.modelService = modelService;
    }

    //region 数据列表

    /**
     * 首页
     *
     * @param model    model模型
     * @param dtoQuery 查询条件
     * @return
     */
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(HttpServletRequest request, Model model, TransportExpenseDTOQuery dtoQuery) {

        //region 初始化
        if (dtoQuery.getShowRecall() == null) {
            dtoQuery.setShowRecall(0);
        }
        if (dtoQuery.getShowReject() == null) {
            dtoQuery.setShowReject(0);
        }
        if (dtoQuery.getShowCancle() == null) {
            dtoQuery.setShowCancle(0);
        }
        if (dtoQuery.getOnlySearchSelf() == null) {
            dtoQuery.setOnlySearchSelf(0);
        }
        if (dtoQuery.getIsUnLimitDate() == null) {
            dtoQuery.setIsUnLimitDate(0);
        }
        if (dtoQuery.getId() != null && dtoQuery.getId() > 0) {
            dtoQuery.setIsUnLimitDate(1);
        }
        //endregion

        // 如果选择“可发放费用”报销单，那么此报销单必处于“报销中”
        if (dtoQuery.getNoBatchNumber() != null && dtoQuery.getNoBatchNumber() == 1) {
            dtoQuery.setBxStatus(1);
        }

        // 报销日期（初始化 30天）
        if (StringUtils.isBlank(dtoQuery.getDaterange())) {
            dtoQuery.setDaterange(String.format("%s ~ %s", DateConvertUtils.getPastDate(30), DateConvertUtils.getPastDate(0)));
        }

        String pin = AdminBaseClass.getPin(request);
        AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);
        Integer myId = modelService.getUserIdByAdminId(curr_obj.getId());

        // 综合报销只显示自己的单子（管理员可以看到所有单子，拥有权限的人也可以查看全部）（修改：不做任何限制）
        //Integer canExec = modelService.getLookAlldataAuthor(pin);   //有没有权限，大于0表示有权限
        //if (dtoQuery.getBxType() == 5 && canExec <= 0) {
        //    //显示与自己有关的报销单，所以不能用adminid
        //    dtoQuery.setSecondaryCurrUser(myId);
        //}

        // 只查自己
        if (dtoQuery.getOnlySearchSelf() == 1) {
            dtoQuery.setBxPeople(myId);
        } else {
            dtoQuery.setBxPeople(modelService.completionUserId(dtoQuery.getBxPeople(), dtoQuery.getBxPeopleCn(), -9999));
        }

        //默认查询的状态：-10撤销 -1驳回 0未报销 1报销中 2已报销
        List<Integer> statuList = new ArrayList<>();
        statuList.add(0);
        statuList.add(1);
        statuList.add(2);
        dtoQuery.setStatuList(statuList);

        dtoQuery.setBxPeople(modelService.completionUserId(dtoQuery.getBxPeople(), dtoQuery.getBxPeopleCn(), -9999));
        dtoQuery.setStopFlag(0);
        dtoQuery.setOrderBy("order by id desc");
        Page<TransportExpenseDTO> dataPage = expenseService.getForPage(dtoQuery);

        BigDecimal BxAmountReal = new BigDecimal(0);      //实际报销金额

        // 实时更新列表信息
        if (dataPage != null && dataPage.getItems().size() > 0) {
            WorkflowApplyLineDTOQuery lineQuery;
            WorkflowApplyLineDTO lineDTO;

            for (TransportExpenseDTO item : dataPage.getItems()) {
                // 报销类型
                item.setBxTypeName(BXTypeEnum.getEnumByKey(item.getBxType()));

                // 报销项目
                item.setBxProjectName(modelService.getCatalogName(item.getBxProject()));

                //收款单位
                item.setCompanyName(modelService.getCompanyName(item.getCompanyId()));

                // 报销人（经办人）
                item.setBxPeopleCn(modelService.getUserTrueName(item.getBxPeople()));

                // 经办人
                item.setBxExtPersonCn(modelService.getManageName(item.getBxExtPerson()));

                // 报销状态
                item.setBxStatusName(BXStatusEnum.getEnumByKey(item.getBxStatus()));

                BxAmountReal = BxAmountReal.add(item.getRealBxAmount());

                // 获取当前审批环节
                if (item.getStopFlag() == 0 && item.getBxStatus() != -1 && item.getBxStatus() != 2 && item.getBxStatus() != 10) {
                    lineQuery = new WorkflowApplyLineDTOQuery();
                    lineQuery.setApplyId(item.getApplyId());
                    lineQuery.setIsCurrent(1);
                    lineDTO = applyLineService.getByQuery(lineQuery);
                    if (lineDTO != null) {
                        item.setApplyNodeSign(lineDTO.getNodeSign());
                        if (StringUtils.isNotBlank(lineDTO.getNodeDescription())) {
                            item.setApplyNodeTitle(lineDTO.getNodeDescription());
                        } else {
                            item.setApplyNodeTitle(lineDTO.getNodeTitle());
                        }
                    }
                }
            }
        }

        model.addAttribute("page", dataPage);
        model.addAttribute("PagePackage", PagePackage(dataPage.getPn(), dataPage.getStart(), dataPage.getPageSize(), dataPage.getTotalPages(), dataPage.getTotalItems()));
        model.addAttribute("dtoQuery", dtoQuery);
        model.addAttribute("BxAmountReal", BxAmountReal);

        //收款单位
        modelService.getCompayPage(model, 2);

        //报销项目
        modelService.getCatalogPage(model, 12, "bxprojectCatalogList");

        //报销日期
        if (StringUtils.isNotBlank(dtoQuery.getDaterange())) {
            String[] date = dtoQuery.getDaterange().split("~");
            if (date.length == 2) {
                model.addAttribute("startDate", date[0].trim());
                model.addAttribute("endDate", date[1].trim());
            }
        }

        //region 显示标题
        //报销类型：1司机费用 2采购报销 3配件报销 4维修报销 5综合报销 6借款申请 7费用支付
        String showTitle;
        switch (dtoQuery.getBxType()) {
            case 1:
                showTitle = "司机";
                break;
            case 2:
                showTitle = "采购";
                break;
            case 3:
                showTitle = "配件";
                break;
            case 4:
                showTitle = "维修";
                break;
            case 5:
                showTitle = "综合";
                break;
            default:
                showTitle = "未知";
                break;
        }
        model.addAttribute("showTitle", showTitle);
        //endregion

        return "erp/expense/index";
    }

    /**
     * 报销单详情
     *
     * @param model model
     * @param id    报销id
     * @return vm
     */
    @RequestMapping(value = "/detail", method = RequestMethod.GET)
    public String detail(Model model, Integer id) {
        if (id == null || id <= 0) {
            throw new RuntimeException("未查询到报销信息");
        }

        TransportExpenseDTO obj = expenseService.getById(id);
        obj.setBxTypeName(BXTypeEnum.getEnumByKey(obj.getBxType()));
        obj.setBxProjectName(modelService.getCatalogName(obj.getBxProject()));
        obj.setAdminName(modelService.getManageName(obj.getAdminId()));
        obj.setBxPeopleCn(modelService.getUserTrueName(obj.getBxPeople()));
        obj.setReviewerCn(modelService.getUserTrueName(obj.getReviewer()));

        //收款单位
        obj.setCompanyName(modelService.getCompanyName(obj.getCompanyId()));

        //付款公司
        obj.setPayCompanyName(modelService.getCompanyName(obj.getPayCompanyId()));

        //付款方式
        obj.setPayWayName(ReceiveWayEnum.getEnumByKey(obj.getPayWay()));

        obj.setBxStatusName(BXStatusEnum.getEnumByKey(obj.getBxStatus()));

        model.addAttribute("bxObj", obj);

        //region 【司机报销】
        if (obj.getBxType() == 1) {

            //获取司机报销单中的行程明细
            TransportExpenseDetailDTOQuery query = new TransportExpenseDetailDTOQuery();
            query.setBxId(id);
            query.setPageSize(1000);
            Page<TransportExpenseDetailDTO> dataPage = expenseDetailService.getForPage(query);

            // 实时更新列表信息
            if (dataPage != null && dataPage.getItems().size() > 0) {
                for (TransportExpenseDetailDTO item : dataPage.getItems()) {
                    item.setCompanyName(modelService.getCompanyName(item.getCompanyId()));
                }
            }
            model.addAttribute("bxPage", dataPage);

        }
        //endregion

        //region 【采购报销】【配件报销】
        if (obj.getBxType() == 2 || obj.getBxType() == 3) {

            //获取明细
            TransportPurchaseDetailDTOQuery detailDTOQuery = new TransportPurchaseDetailDTOQuery();
            detailDTOQuery.setBxId(id);
            detailDTOQuery.setStopFlag(0);
            detailDTOQuery.setPageSize(1000);
            Page<TransportPurchaseDetailDTO> dataPage = purchaseDetailService.getForPage(detailDTOQuery);

            BigDecimal total = new BigDecimal(0); //总计
            for (TransportPurchaseDetailDTO item : dataPage.getItems()) {
                item.setrPurchaserName(modelService.getManageName(item.getrPurchaser()));
                item.setPartName(modelService.getPurchaseName(item.getPartId()));

                total = total.add(item.getrAmount());
            }
            model.addAttribute("purchasePage", dataPage);
            model.addAttribute("total", total);

        }
        //endregion

        //region 当前申请人的借款信息
        //条件：当前申请人、已完成审批、关联ID为空和当前ID
        TransportExpenseDTOQuery applyQuery = new TransportExpenseDTOQuery();
        applyQuery.setBxType(6);
        applyQuery.setBxPeople(obj.getBxPeople());
        applyQuery.setBxStatus(2);
        applyQuery.setRelationId(obj.getId());
        applyQuery.setPageSize(100);
        Page<TransportExpenseDTO> applyPage = expenseService.getForPage(applyQuery);
        for (TransportExpenseDTO item : applyPage.getItems()) {
            item.setBxProjectName(modelService.getCatalogName(item.getBxProject()));
            item.setBxPeopleCn(modelService.getUserTrueName(item.getBxPeople()));
        }
        model.addAttribute("applyPage", applyPage);
        //endregion

        //region 当前申请人的支付信息
        TransportExpenseDTOQuery payQuery = new TransportExpenseDTOQuery();
        payQuery.setBxType(7);
        payQuery.setBxPeople(obj.getBxPeople());
        payQuery.setBxStatus(2);
        payQuery.setRelationId(obj.getId());
        payQuery.setPageSize(100);
        Page<TransportExpenseDTO> payPage = expenseService.getForPage(payQuery);
        for (TransportExpenseDTO item : payPage.getItems()) {
            item.setBxProjectName(modelService.getCatalogName(item.getBxProject()));
            item.setBxPeopleCn(modelService.getUserTrueName(item.getBxPeople()));
        }
        model.addAttribute("payPage", payPage);
        //endregion

        //region 显示标题
        //报销类型：1司机费用 2采购报销 3配件报销 4维修报销 5综合报销 6借款申请 7费用支付
        String showTitle;
        switch (obj.getBxType()) {
            case 1:
                showTitle = "司机";
                break;
            case 2:
                showTitle = "采购";
                break;
            case 3:
                showTitle = "配件";
                break;
            case 4:
                showTitle = "维修";
                break;
            case 5:
                showTitle = "综合";
            case 6:
                showTitle = "借款";
            case 7:
                showTitle = "费用支付";
                break;
            default:
                showTitle = "未知";
                break;
        }
        model.addAttribute("showTitle", showTitle);
        //endregion

        return "erp/expense/detail";
    }

    //endregion

    //region 编辑&保存

    /**
     * 编辑
     *
     * @param model        model模型
     * @param id           主键id
     * @param bxType       报销类型：1司机费用 2采购报销 3配件报销 4维修报销 5综合报销 6借款申请 7费用支付
     * @param purchaseType 采购类型：1汽车配件 2日常采购
     * @param detailIds    需要报销的物料ID集合
     * @param copyId       复制ID
     * @return vm
     */
    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String edit(HttpServletRequest request, Model model, Integer id, Integer bxType, Integer purchaseType, String detailIds, Integer copyId) {
        if (id == null || id <= 0) {
            id = 0;
        }

        if (bxType == null || bxType <= 0) {
            throw new RuntimeException("请选择正确的报销类型！");
        }

        if (purchaseType == null || purchaseType <= 0) {
            purchaseType = 0;
        }

        if (bxType == 2) {
            purchaseType = 2;
        }
        if (bxType == 3) {
            purchaseType = 1;
        }

        String pin = AdminBaseClass.getPin(request);
        AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);

        TransportExpenseDTO obj;

        //region 报销信息，如果是新增则赋予初始值
        if (id > 0) {
            obj = expenseService.getById(id);
            obj.setBxPeopleCn(modelService.getUserTrueName(obj.getBxPeople()));
            obj.setReviewerCn(modelService.getUserTrueName(obj.getReviewer()));
            bxType = obj.getBxType();

        } else {
            obj = new TransportExpenseDTO();
            obj.setId(0);
            obj.setBxType(bxType);
            obj.setPayWay(1);
            obj.setBxAmount(new BigDecimal(0));
            obj.setRealBxAmount(new BigDecimal(0));
            obj.setBxDate(new Date());
            obj.setPayDate(obj.getBxDate());

            int uid = modelService.getUserIdByAdminId(curr_obj.getId());
            obj.setBxPeople(uid);
            obj.setBxPeopleCn(curr_obj.getNickName());

            //复核人：获取部门负责人
            obj.setReviewerCn(modelService.getUserTrueName(obj.getReviewer()));

            String preTitle = "未知";
            String lastTitle = "";

            //I.  如果是维修报销
            if (bxType == 4) {
                WorkflowBusinessDTO bDTO = businessService.getByEnName("repair_expense");
                if (bDTO != null) {
                    obj.setBusinessId(bDTO.getId());
                }

                preTitle = "请简要填写维修说明";
                lastTitle = "维修";
                obj.setBxProject(515);  //维修费
            }

            //II. 如果是综合报销
            if (bxType == 5) {
                WorkflowBusinessDTO bDTO = businessService.getByEnName("daily_expense");
                if (bDTO != null) {
                    obj.setBusinessId(bDTO.getId());
                }

                preTitle = "请简要填写报销名称";
                obj.setBxProject(520);  //办公费
            }

            obj.setBxName(String.format("%s的（%s）%s报销单", obj.getBxPeopleCn(), preTitle, lastTitle));
        }
        //endregion

        //region 复制功能
        if (copyId != null && copyId > 0) {
            obj = expenseService.getById(copyId);
        }

        // 如果当前使用的是复制功能，则需要清空一些数据
        if (copyId != null && copyId > 0) {
            if (obj == null) {
                obj = new TransportExpenseDTO();
            } else {
                obj.setBxPeopleCn(modelService.getUserTrueName(obj.getBxPeople()));
                obj.setReviewerCn(modelService.getUserTrueName(obj.getReviewer()));
                bxType = obj.getBxType();
            }

            obj.setId(0);
            obj.setBatchNumber(null);
            obj.setRelationId(0);
            obj.setBookidsArray(null);
            obj.setBookIds(null);
            obj.setApplyId(0);
        }
        //endregion

        //报销类型：1司机费用 2采购报销 3配件报销 4维修报销 5综合报销 6借款申请 7费用支付

        //region 【司机报销】
        if (bxType == 1) {

            //获取报销单中的行程明细
            TransportExpenseDetailDTOQuery query = new TransportExpenseDetailDTOQuery();
            query.setBxId(id);
            query.setPageSize(1000);
            Page<TransportExpenseDetailDTO> dataPage = expenseDetailService.getForPage(query);

            // 实时更新列表信息
            if (dataPage != null && dataPage.getItems().size() > 0) {
                for (TransportExpenseDetailDTO item : dataPage.getItems()) {
                    item.setCompanyName(modelService.getCompanyName(item.getCompanyId()));
                }
            }
            model.addAttribute("page", dataPage);
        }
        //endregion

        //region 【采购报销】【配件报销】
        if (bxType == 2 || bxType == 3) {

            if (id > 0) {
                //编辑
                //获取明细
                TransportPurchaseDetailDTOQuery detailDTOQuery = new TransportPurchaseDetailDTOQuery();
                detailDTOQuery.setBxId(id);
                detailDTOQuery.setStopFlag(0);
                Page<TransportPurchaseDetailDTO> dataPage = purchaseDetailService.getForPage(detailDTOQuery);
                for (TransportPurchaseDetailDTO item : dataPage.getItems()) {
                    item.setrPurchaserName(modelService.getManageName(item.getrPurchaser()));
                    item.setPartName(modelService.getPurchaseName(item.getPartId()));
                    item.setrCompanyName(modelService.getCompanyName(item.getrCompanyId()));
                }
                model.addAttribute("page", dataPage);

            } else {
                //新增
                List<Integer> idlist = FormatUtils.commaToList_Integer(detailIds);

                //获取明细
                TransportPurchaseDetailDTOQuery detailDTOQuery = new TransportPurchaseDetailDTOQuery();
                detailDTOQuery.setPurchaseType(purchaseType);
                detailDTOQuery.setOpType(1);        //1采购 2出库 3损坏
                detailDTOQuery.setBxId(0);          //表示未生成过报销单
                detailDTOQuery.setPageSize(1000);   //最大只能获取1000条
                detailDTOQuery.setStopFlag(0);
                detailDTOQuery.setIds(idlist);
                Page<TransportPurchaseDetailDTO> dataPage = purchaseDetailService.getForPage(detailDTOQuery);

                List<Integer> effectiveIds = new ArrayList<>();
                AnalysisManageDTO manageDTO;
                Integer userid = 0;

                for (TransportPurchaseDetailDTO item : dataPage.getItems()) {
                    if (item == null) {
                        continue;
                    }

                    manageDTO = manageService.getFromCacheId(item.getrPurchaser());
                    if (manageDTO == null) {
                        continue;
                    }

                    item.setrPurchaserName(manageDTO.getNickName());
                    item.setPartName(modelService.getPurchaseName(item.getPartId()));
                    item.setrCompanyName(modelService.getCompanyName(item.getrCompanyId()));

                    obj.setBxAmount(obj.getBxAmount().add(item.getrAmount()));

                    effectiveIds.add(item.getId());
                }

                model.addAttribute("page", dataPage);

                String preTitle = "未知";
                if (purchaseType == 1) {
                    preTitle = "配件";
                }
                if (purchaseType == 2) {
                    preTitle = "采购";
                }

                obj.setRealBxAmount(obj.getBxAmount());
                obj.setBxDate(new Date());
                obj.setBxName(String.format("%s的（请填写%s简称）报销单", obj.getBxPeopleCn(), preTitle));
                obj.setBookIds(StringUtils.join(effectiveIds.toArray(), ","));
            }
        }
        //endregion

        //region 【维修报销】【综合报销】
        if (bxType == 4 || bxType == 5) {
            AnalysisVisualCatalogDTO catalogDTO = catalogService.getByCateEnName("baoxiaoliucheng");

            WorkflowBusinessDTOQuery query = new WorkflowBusinessDTOQuery();
            query.setCatalogId(catalogDTO == null ? 0 : catalogDTO.getId());
            query.setBusinessType(1);
            query.setStopFlag(0);
            Page<WorkflowBusinessDTO> flowPage = businessService.getForPage(query);
            model.addAttribute("flowPage", flowPage);
        }
        //endregion

        //报销项目
        modelService.getCatalogPage(model, 12, "bxProjectList");

        //付款单位
        modelService.getCompayPage(model, 7, null, "receivePayList");

        //付款方式
        model.addAttribute("receiveWayList", ReceiveWayEnum.getEnumList());

        //通过adminid 取出userid
        Integer userid = modelService.getUserIdByAdminId(curr_obj.getId());

        //region 当前申请人的借款信息
        //条件：当前申请人、已完成审批、关联ID为空和当前ID
        TransportExpenseDTOQuery applyQuery = new TransportExpenseDTOQuery();
        applyQuery.setBxType(6);    //借款
        applyQuery.setBxPeople(userid);
        applyQuery.setBxStatus(2);
        applyQuery.setCurr_relation(obj.getId());
        applyQuery.setPageSize(100);
        Page<TransportExpenseDTO> applyPage = expenseService.getForPage(applyQuery);
        for (TransportExpenseDTO item : applyPage.getItems()) {
            item.setBxProjectName(modelService.getCatalogName(item.getBxProject()));
            item.setBxPeopleCn(modelService.getUserTrueName(item.getBxPeople()));

            if (item.getRelationId() != null && item.getRelationId() > 0) {
                if (StringUtils.isBlank(obj.getBorrowIds())) {
                    obj.setBorrowIds(item.getId() + ":" + item.getRealUseAmount());
                } else {
                    obj.setBorrowIds(obj.getBorrowIds() + "," + item.getId() + ":" + item.getRealUseAmount());
                }
            }
        }
        model.addAttribute("applyPage", applyPage);
        //endregion

        //region 当前申请人的支付信息
        TransportExpenseDTOQuery payQuery = new TransportExpenseDTOQuery();
        payQuery.setBxType(7);  //支付
        payQuery.setBxPeople(userid);
        payQuery.setBxStatus(2);
        payQuery.setCurr_relation(obj.getId());
        payQuery.setPageSize(100);
        Page<TransportExpenseDTO> payPage = expenseService.getForPage(payQuery);
        for (TransportExpenseDTO item : payPage.getItems()) {
            item.setBxProjectName(modelService.getCatalogName(item.getBxProject()));
            item.setBxPeopleCn(modelService.getUserTrueName(item.getBxPeople()));

            if (item.getRelationId() != null && item.getRelationId() > 0) {
                if (StringUtils.isBlank(obj.getPayIds())) {
                    obj.setPayIds(item.getId() + ":" + item.getRealUseAmount());
                } else {
                    obj.setPayIds(obj.getPayIds() + "," + item.getId() + ":" + item.getRealUseAmount());
                }
            }
        }
        model.addAttribute("payPage", payPage);
        //endregion

        model.addAttribute("Obj", obj);

        //region 显示标题
        //报销类型：1司机费用 2采购报销 3配件报销 4维修报销 5综合报销 6借款申请 7费用支付
        String showTitle;
        switch (bxType) {
            case 1:
                showTitle = "司机";
                break;
            case 2:
                showTitle = "采购";
                break;
            case 3:
                showTitle = "配件";
                break;
            case 4:
                showTitle = "维修";
                break;
            case 5:
                showTitle = "综合";
                break;
            default:
                showTitle = "未知";
                break;
        }
        model.addAttribute("showTitle", showTitle);
        //endregion

        return "erp/expense/edit";
    }

    /**
     * 保存 ajax异步
     *
     * @param request sevelet请求
     * @param objDTO  实体类
     * @return json
     */
    @RequestMapping(value = "/saveEdit", method = RequestMethod.POST)
    @ResponseBody
    public String saveEditNotify(HttpServletRequest request, TransportExpenseDTO objDTO) {

        // 结果返回 结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        try {
            //报销名称长度不能超过128
            if (objDTO.getBxName().length() > 128) {
                map = OperateCode.CompositionResult(map, -10, "报销单名称太长！");
                result = JSONUtils.toJSON(map);
                return result;
            }

            //除了【司机报销】之外，其它的都需要填写复核人
            if (objDTO.getBxType() != 1) {
                if (objDTO.getReviewer() == null || objDTO.getReviewer() <= 0) {
                    map = OperateCode.CompositionResult(map, -10, "请填写报销复核人！");
                    result = JSONUtils.toJSON(map);
                    return result;
                }
            }

            //报销项目必填
            if (objDTO.getBxProject() == null || objDTO.getBxProject() <= 0) {
                map = OperateCode.CompositionResult(map, -10, "请选择报销项目！");
                result = JSONUtils.toJSON(map);
                return result;
            }

            //【综合报销】必须选择报销流程
            if (objDTO.getBxType() == 5 && objDTO.getBusinessId() != null && objDTO.getBusinessId() == 0) {
                map = OperateCode.CompositionResult(map, -10, "请选择报销流程！");
                result = JSONUtils.toJSON(map);
                return result;
            }

            //日期
            objDTO.setBxDate(DateConvertUtils.strToShortDate(objDTO.getBxDateSr()));
            objDTO.setPayDate(DateConvertUtils.strToShortDate(objDTO.getPayDateSr()));

            //只有【综合报销】有值
            if (objDTO.getBusinessId() == null) {
                objDTO.setBusinessId(0);
            }

            //为了下面可以处理其它事务
            TransportExpenseDTO tempDTO = objDTO;

            //审批ID
            Integer applyId = objDTO.getApplyId();

            //业务流程，不同业务有各自的流程
            String businessName = "";

            String pin = AdminBaseClass.getPin(request);
            AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);

            if (objDTO.getId() == null || objDTO.getId() <= 0) {

                //检查是否有明细行程（司机报销和采购报销、配件报销）
                List<Integer> idList = FormatUtils.commaToList_Integer(objDTO.getBookIds());
                if (objDTO.getBxType() == 1 || objDTO.getBxType() == 2 || objDTO.getBxType() == 3) {
                    if (idList.size() == 0) {
                        map = OperateCode.CompositionResult(map, -10, "没有查询到采购信息，无法生成报销单！");
                        result = JSONUtils.toJSON(map);
                        return result;
                    }
                }

                //int purchaseType = objDTO.getPurchaseType();

                //region STEP 01 伪事务 - 新增
                objDTO.setParentId(0);
                objDTO.setBxNo(GeneralUtils.GenTimeSeries(4, null, null));    //生成报销单号
                if (objDTO.getReviewer() == null || objDTO.getReviewer() <= 0) {
                    objDTO.setReviewer(0);
                }
                if (objDTO.getBxType() != 4) {  //只有维修时才有车辆ID和司机ID
                    objDTO.setCarId(0);
                    objDTO.setDriverId(0);
                }
                if (objDTO.getCompanyId() == null) {
                    objDTO.setCompanyId(0);
                }

                objDTO.setRealUseAmount(new BigDecimal(0));
                objDTO.setReviewDate(DateConvertUtils.strToShortDate("1990-01-01"));
                objDTO.setReviewStatus(0);
                objDTO.setBxExtPerson(curr_obj.getId());
                objDTO.setBxStatus(0);
                objDTO.setRelationId(0);
                objDTO.setBookidsArray(StringUtils.join(idList, ","));
                objDTO.setApplyId(0);
                objDTO.setAdminId(curr_obj.getId());
                objDTO.setCreateTime(new Date());
                objDTO.setStopFlag(0);
                objDTO.setDeleteFlag(0);

                objDTO = expenseService.insert(objDTO);

                if (objDTO == null || objDTO.getId() <= 0) {
                    //程序终止，返回失败信息
                    map = OperateCode.CompositionResult(map, -1);
                    result = JSONUtils.toJSON(map);
                    return result;
                }
                //endregion

                //region STEP 02 - 处理各自业务（报销类型：1司机费用 2采购报销 3配件报销 4维修报销 5综合报销 6借款申请 7费用支付）

                //region A. 司机报销

                //endregion

                //region B. 采购报销 和 配件报销
                if (objDTO.getBxType() == 2 || objDTO.getBxType() == 3) {

                    //region 1. 设置采购明细中的bx_id
                    TransportPurchaseDetailDTOQuery updateQuery = new TransportPurchaseDetailDTOQuery();
                    updateQuery.setBxId(objDTO.getId());
                    updateQuery.setIds(idList);
                    Boolean isNext = purchaseDetailService.updateInfoByQuery(updateQuery);
                    if (!isNext) {
                        //更新失败，将已生成的报销单设置为无效
                        expenseService.changeState(objDTO.getId(), 1);

                        //程序终止，返回失败信息
                        map = OperateCode.CompositionResult(map, -1);
                        result = JSONUtils.toJSON(map);
                        return result;
                    }
                    //endregion

                }
                //endregion

                //endregion

                //region STEP 03 - 事务 - 生成审批流程

                //流程标题前缀
                Map<String, String> param = new HashMap<>();

                //A.【司机报销】
                if (objDTO.getBxType() == 1) {
                    businessName = "driver_bx";
                    param.put("preTitle", objDTO.getBxName().replace("报销单", ""));
                }

                //B.【采购报销】
                if (objDTO.getBxType() == 2) {
                    businessName = "purchase_expense";
                    param.put("applyTitle", objDTO.getBxName().replace("报销单", ""));

                    //如果0元报销单，则无需审批
                    if (objDTO.getRealBxAmount().compareTo(BigDecimal.ZERO) == 0) {
                        businessName = "norequire_expense";
                    }
                }

                //C.【配件报销】
                if (objDTO.getBxType() == 3) {
                    businessName = "parts_expense";
                    param.put("applyTitle", objDTO.getBxName().replace("报销单", ""));

                    //如果0元报销单，则无需审批
                    if (objDTO.getRealBxAmount().compareTo(BigDecimal.ZERO) == 0) {
                        businessName = "norequire_expense";
                    }
                }

                //D.【维修报销】
                if (objDTO.getBxType() == 4) {
                    businessName = "repair_expense";
                    param.put("applyTitle", objDTO.getBxName().replace("报销单", ""));
                }

                //E.【综合报销】
                if (objDTO.getBxType() == 5) {
                    businessName = "daily_expense";

                    //根据所选的流程获取流程标识（因为可以报销很多流程，默认是综合报销）
                    if (objDTO.getBusinessId() > 0) {
                        WorkflowBusinessDTO businessDTO = businessService.getById(objDTO.getBusinessId());
                        if (businessDTO != null) {
                            businessName = businessDTO.getBusinessNameEn();
                        }
                    }

                    param.put("applyTitle", objDTO.getBxName().replace("报销单", ""));
                }

                //设定第一、二审批人
                //[改版后]审批人走的是会员系统
                param.put("firstExector", objDTO.getBxPeople() + "");
                param.put("secondExector", objDTO.getReviewer() + "");

                applyId = transactionService.createApplyWithout(businessName, "transport_expense", objDTO.getId(), objDTO.getBxExtPerson(), param);

                if (applyId > 0) {

                    //region 更新报销表中的applyid
                    TransportExpenseDTO updateDto = new TransportExpenseDTO();
                    updateDto.setId(objDTO.getId());
                    updateDto.setApplyId(applyId);
                    expenseService.updateInfoById(updateDto);
                    //endregion

                } else {

                    // 1. 审批流程生成失败, 将已生成的报销单设置为无效
                    expenseService.changeState(objDTO.getId(), 1);

                    //【司机报销】

                    //程序终止，返回失败信息
                    map = OperateCode.CompositionResult(map, -1);
                    result = JSONUtils.toJSON(map);
                    return result;
                }

                //endregion

            } else {

                //region 更新 只能更新个别信息
                TransportExpenseDTO update = new TransportExpenseDTO();
                update.setId(objDTO.getId());
                update.setBxName(objDTO.getBxName());
                update.setBxProject(objDTO.getBxProject());
                update.setRealBxAmount(objDTO.getRealBxAmount());
                update.setBxPeople(objDTO.getBxPeople());
                update.setReviewer(objDTO.getReviewer());
                update.setBxDate(objDTO.getBxDate());
                update.setCompanyId(objDTO.getCompanyId());
                update.setOpenBack(objDTO.getOpenBack());
                update.setBackAccount(objDTO.getBackAccount());
                update.setLinkName(objDTO.getLinkName());
                update.setLinkMobile(objDTO.getLinkMobile());
                update.setPayCompanyId(objDTO.getPayCompanyId());
                update.setPayWay(objDTO.getPayWay());
                update.setPayDate(objDTO.getPayDate());
                update.setInvoiceNo(objDTO.getInvoiceNo());
                if (objDTO.getBxType() == 4) {
                    update.setCarId(objDTO.getCarId());
                    update.setDriverId(objDTO.getDriverId());
                }
                update.setRemark(objDTO.getRemark());

                Boolean isNext = expenseService.updateInfoById(update);

                if (isNext) {

                    //region 更新第1审批人和每2审批人
                    if (objDTO.getApplyId() > 0) {
                        Integer firstExector = objDTO.getBxPeople();
                        Integer secondExector = objDTO.getReviewer();

                        Map<Integer, Integer> replaceMap = new HashMap<>();
                        replaceMap.put(1, firstExector);
                        replaceMap.put(2, secondExector);
                        transactionService.setExector(objDTO.getApplyId(), replaceMap);
                    }
                    //endregion

                    //region 同时更新审批单名称
                    if (objDTO.getApplyId() > 0 && objDTO.getBxType() >= 1 && objDTO.getBxType() <= 5) {
                        String applyTitle = objDTO.getBxName().replace("报销单", "审批单");

                        WorkflowApplyDTOQuery updateQuery = new WorkflowApplyDTOQuery();
                        updateQuery.setApplyTitle(applyTitle);
                        updateQuery.setW_id(objDTO.getApplyId());
                        applyService.updateInfoByQuery(updateQuery);
                    }
                    //endregion

                } else {
                    //操作失败
                    map = OperateCode.CompositionResult(map, -1);
                    result = JSONUtils.toJSON(map);
                    return result;
                }
                //endregion
            }

            //region 操作完成后判断金额是否大于300，如果大于300则启用经理审批
            businessNodeService.handleJudgeApply(businessName, 1, objDTO.getRealBxAmount(), applyId);
            //endregion

            //region 费用单 操作完成后更新【借款】和【费用支付】的relationid

            //<!-- 格式：id:money,id:money -->

            //A. 将旧信息的relationid 更新为0，实际使用金额为0
            Integer userid = modelService.getUserIdByAdminId(curr_obj.getId());

            List<String> applyList = FormatUtils.commaToList_String(tempDTO.getBorrowIds());
            List<String> payList = FormatUtils.commaToList_String(tempDTO.getPayIds());
            applyList.addAll(payList);

            if (applyList.size() > 0) {
                List<Integer> updateIdList = new ArrayList<>();
                for (String item : applyList) {
                    Integer id = Integer.valueOf(item.split(":")[0]);
                    if (id <= 0) {
                        continue;
                    }

                    //取出原始对象
                    TransportExpenseDTO autorDTO = expenseService.getById(id);
                    if (autorDTO == null) {
                        continue;
                    }

                    //当前用户权限认证
                    //1.报销人不是本人
                    //2.报销状态不是已完成
                    //3、不是当前报销单使用的
                    if (!Objects.equals(autorDTO.getBxPeople(), userid) || autorDTO.getBxStatus() != 2 || !Objects.equals(autorDTO.getRelationId(), objDTO.getId())) {
                        continue;
                    }

                    updateIdList.add(id);
                }

                TransportExpenseDTOQuery updateQuery = new TransportExpenseDTOQuery();
                updateQuery.setRelationId(0);
                updateQuery.setRealUseAmount(new BigDecimal(0));
                updateQuery.setIds(updateIdList);
                expenseService.updateInfoByQuery(updateQuery);
            }

            //B. 将新信息的relationid 更新为objDTO.id
            List<String> newApplyList = FormatUtils.commaToList_String(tempDTO.getNewBorrowIds());
            List<String> newPayList = FormatUtils.commaToList_String(tempDTO.getNewPayIds());
            newApplyList.addAll(newPayList);

            if (newApplyList.size() > 0) {
                for (String item : newApplyList) {
                    Integer id = Integer.valueOf(item.split(":")[0]);
                    String amount_str = item.split(":")[1];

                    if (StringUtils.isBlank(amount_str) || Objects.equals(amount_str, "0")) {
                        //如果没有使用金额，是不进行处理。
                        continue;
                    }

                    BigDecimal amount = new BigDecimal(amount_str);

                    //取出原因对象
                    TransportExpenseDTO originDTO = expenseService.getById(id);

                    //当前用户权限认证
                    //1、报销人不是本人
                    //2、报销状态不是已完成
                    //3、必须是未使用的
                    if (!Objects.equals(originDTO.getBxPeople(), userid) || originDTO.getBxStatus() != 2 || originDTO.getRelationId() != 0) {
                        continue;
                    }

                    //如果“使用金额” > “本身金额”，则跳过。
                    if (amount.compareTo(originDTO.getRealBxAmount()) > 0) {
                        continue;
                    }

                    if (amount.compareTo(originDTO.getRealBxAmount()) < 0) {
                        //如果“冲销金额” < “本身金额”，则需要进行拆单，返回新的拆单ID。
                        id = splitExpenseOrder(originDTO, amount);
                    }

                    //做一下过滤
                    if (id <= 0) {
                        continue;
                    }

                    //更新关联ID 和实际冲销金额
                    TransportExpenseDTO updateDto = new TransportExpenseDTO();
                    updateDto.setRelationId(objDTO.getId());
                    updateDto.setRealUseAmount(amount);
                    updateDto.setId(id);
                    expenseService.updateInfoById(updateDto);
                }
            }

            //endregion

            //region *** 更新信息完毕记录操作日志 ***
            logService.insertSimple(1, 45, objDTO.getId(), 2,
                    "更新报销单",
                    FastJsonUtils.toJSONString(objDTO),
                    curr_obj.getId(),
                    IpUtils.getClientIp(request),
                    SystemUtils.getBrowserInfo(request));
            //endregion

            //操作成功 结果返回
            map = OperateCode.CompositionResult(map, 1, "报销单生成成功！");
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }

    /**
     * 拆单（启用事务）
     *
     * @param dto    主单完整对象
     * @param amount 当前使用金额
     * @return 新单ID
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Integer splitExpenseOrder(TransportExpenseDTO dto, BigDecimal amount) {
        Integer id = 0;
        Integer origin_id = dto.getId();  //主单ID
        BigDecimal totalAmount = dto.getRealBxAmount(); //总金额
        BigDecimal surplus = dto.getRealBxAmount().subtract(amount); //剩余金额

        //更新原订单为已拆单
        TransportExpenseDTO update = new TransportExpenseDTO();
        update.setId(origin_id);
        update.setRealUseAmount(amount); //本次实际使用金额
        update.setBxStatus(10); //已拆单
        Boolean isNext = expenseService.updateInfoById(update);
        if (!isNext) {
            return id;
        }

        //拆单1：使用金额单
        dto.setId(0);
        dto.setParentId(origin_id);
        dto.setBxAmount(totalAmount);
        dto.setRealBxAmount(amount);
        dto = expenseService.insert(dto);
        id = dto.getId();

        //拆单2：剩余金额单
        dto.setId(0);
        dto.setParentId(origin_id);
        dto.setBxAmount(totalAmount);
        dto.setRealBxAmount(surplus);
        expenseService.insert(dto);

        return id;
    }

    //endregion

    //region 改变状态

    /**
     * 取消报销单
     *
     * @param id     记录id
     * @param status 状态 1表示取消
     * @return
     */
    @RequestMapping(value = "/changeStatus", method = RequestMethod.POST)
    @ResponseBody
    public String changeStatus(HttpServletRequest request, Integer id, Integer status) {

        // 结果返回 结果至少包含一个操作状态和一条状态信息
        String result = "";
        Map<String, String> map = new HashMap<String, String>();

        try {
            String pin = AdminBaseClass.getPin(request);
            AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);
            Boolean isNext = cancleCheckout(id, curr_obj.getId());

            //region *** 更新信息完毕记录操作日志 ***
            logService.insertSimple(1, 45, id, 2,
                    "取消报销单",
                    "取消" + (isNext ? "成功" : "失败") + "：" + id,
                    curr_obj.getId(),
                    IpUtils.getClientIp(request),
                    SystemUtils.getBrowserInfo(request));
            //endregion

            map = OperateCode.CompositionResult(map, isNext ? 1 : 0);
            result = JSONUtils.toJSON(map);
            return result;

        } catch (Exception e) {
            //清空map
            map.clear();
            map = OperateCode.CompositionResult(map, -1);
            result = JSONUtils.toJSON(map);
            return result;
        }
    }

    //endregion

    //region "撤消"报销单

    /**
     * 撤消报销单
     *
     * @param id 结账单id
     * @return true or false
     */
    private Boolean cancleCheckout(Integer id, Integer adminId) {
        if (id == null || id <= 0) {
            return false;
        }

        //1. 取消报销单状态
        Boolean isNext = expenseService.changeState(id, 1);

        //2. 将订单状态设置为未报销
        if (isNext) {
            TransportExpenseDTO dto = expenseService.getById(id);
            List<Integer> idList;
            if (dto != null) {
                //3. 撤消审批
                if (dto.getApplyId() > 0) {
                    // 根据 applyid 获取最新审批环节
                    // 自动走完当前审批环节（调用一次审批方法）
                    transactionService.autoApplyCurrNode(dto.getApplyId(), -10, adminId);
                }
            }
        }

        return isNext;
    }
    //endregion

    //region 发放费用

    /**
     * 获取发放费用
     *
     * @param model
     * @param ids   报销单ID集合，如果为空则选择所有可以发放费用的报销单
     * @return
     */
    @RequestMapping(value = "/sendPayFee", method = RequestMethod.POST)
    public String sendPayFee(Model model, String ids) {

        //处理 “,5,6,7,” 为List
        List<Integer> idList = FormatUtils.commaToList_Integer(ids);

        TransportExpenseDTOQuery query = new TransportExpenseDTOQuery();
        if (idList.size() > 0) {
            query.setIds(idList);
        }
        query.setBxType(1); //目前只能发放司机报销的费用
        query.setBxStatus(1);
        query.setNoBatchNumber(1);  //批次号，发放完费用以后会生成一个批次号
        query.setStopFlag(0);
        Page<TransportExpenseDTO> dataPage = expenseService.getForPage(query);

        // 实时更新列表信息
        BigDecimal BxAmountReal = new BigDecimal(0);      //实际报销金额合计
        List<Integer> effectiveIds = new ArrayList<>();
        if (dataPage != null && dataPage.getItems().size() > 0) {
            for (TransportExpenseDTO item : dataPage.getItems()) {
                item.setBxTypeName(modelService.getCatalogName(item.getBxType()));
                item.setBxProjectName(modelService.getCatalogName(item.getBxProject()));
                item.setBxPeopleCn(modelService.getUserTrueName(item.getBxPeople()));
                item.setBxExtPersonCn(modelService.getManageName(item.getBxExtPerson()));
                item.setBxStatusName(BXStatusEnum.getEnumByKey(item.getBxStatus()));

                BxAmountReal = BxAmountReal.add(item.getRealBxAmount());
                effectiveIds.add(item.getId());
            }
        }

        model.addAttribute("page", dataPage);
        model.addAttribute("BxAmountReal", BxAmountReal);
        model.addAttribute("ids", StringUtils.join(effectiveIds.toArray(), ","));

        //获取员工信息
        modelService.getManagerPage(model);

        return "erp/expense/send-pay-fee";
    }

    /**
     * 保存发放费用
     *
     * @param request
     * @param ids          报销单id集合
     * @param payFeePeople 费用发放人
     * @return
     */
    @RequestMapping(value = "/saveSendPayFee", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> saveSendPayFee(HttpServletRequest request, String ids, Integer payFeePeople) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("returnCode", 0);

        //处理 “,5,6,7,” 为List
        List<Integer> idList = FormatUtils.commaToList_Integer(ids);

        String pin = AdminBaseClass.getPin(request);
        AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);

        if (idList.size() > 0) {
            TransportExpenseDTOQuery updateQuery = new TransportExpenseDTOQuery();
            updateQuery.setIds(idList);
            updateQuery.setBatchNumber(GeneralUtils.GenTimeSeries(0, null, null));
            updateQuery.setReviewer(modelService.getUserIdByAdminId(curr_obj.getId()));
            updateQuery.setReviewDate(new Date());
            updateQuery.setReviewStatus(1);
            Boolean isNext = expenseService.updateInfoByQuery(updateQuery);

            if (isNext) {

                //获取流程业务ID（Key：driver_bx）
                WorkflowBusinessDTO business = businessService.getByEnName("driver_bx");
                if (business == null) {
                    map.put("returnMessage", "费用发放失败！");
                }

                //region 更新：自动走环节2；并更新环节3的审核人。

                //循环更新
                TransportExpenseDTOQuery query = new TransportExpenseDTOQuery();
                query.setIds(idList);
                Page<TransportExpenseDTO> dataPage = expenseService.getForPage(query);

                for (TransportExpenseDTO item : dataPage.getItems()) {

                    // 获取(环节2)财务主管发放费用
                    // 自动走(环节2)财务主管发放费
                    String remark = "批次号：" + updateQuery.getBatchNumber();
                    transactionService.autoApply(business.getId(), item.getApplyId(), KeyConstants.LINENODE_DRIVER_BX_FEIYONGFAFANG, remark, curr_obj.getId());

                    // 获取(环节3)发放费用信息
                    Integer lineId = applyLineService.getLineIdByNodesign(business.getId(), item.getApplyId(), KeyConstants.LINENODE_DRIVER_BX_EXECFEIYONG);
                    WorkflowApplyLineDTO update = new WorkflowApplyLineDTO();
                    update.setApprover(payFeePeople);   //费用发放审批人
                    update.setId(lineId);
                    applyLineService.updateInfoById(update);
                }

                //endregion

                map.put("returnCode", 1);
                map.put("returnMessage", "费用发放成功！");

            } else {
                map.put("returnMessage", "费用发放失败！");
            }

            //region *** 更新信息完毕记录操作日志 ***
            logService.insertSimple(1, 45, 0, 2,
                    "财务发放费用",
                    "财务发放结果" + (isNext ? "成功" : "失败") + "：" + ids,
                    curr_obj.getId(),
                    IpUtils.getClientIp(request),
                    SystemUtils.getBrowserInfo(request));
            //endregion

        }

        return map;
    }

    //endregion

    //region 配件、采购报销 选择列表

    /**
     * 配件、采购报销
     *
     * @param model    model模型
     * @param dtoQuery purchaseType：0其它 1汽车配件 2日常采购
     * @return
     */
    @RequestMapping(value = "/expense", method = RequestMethod.GET)
    public String expense(HttpServletRequest request, Model model, TransportPurchaseDetailDTOQuery dtoQuery) {

        int bxType = 0;
        if (dtoQuery.getPurchaseType() == 1) { //配件
            bxType = 3;
        }
        if (dtoQuery.getPurchaseType() == 2) { //采购
            bxType = 2;
        }
        model.addAttribute("bxType", bxType);

        //获取明细
        dtoQuery.setOpType(1);        //1入库 2出库 3损坏
        dtoQuery.setrPurchaseType(1); //入库形式：1采购 2提报
        dtoQuery.setBxId(0);          //未生成过报销单
        dtoQuery.setPageSize(100);    //100条/页
        dtoQuery.setStopFlag(0);
        dtoQuery.setOrderBy("order by id desc");
        Page<TransportPurchaseDetailDTO> dataPage = purchaseDetailService.getForPage(dtoQuery);

        for (TransportPurchaseDetailDTO item : dataPage.getItems()) {
            if (item == null) {
                continue;
            }

            item.setrPurchaserName(modelService.getManageName(item.getrPurchaser()));
            item.setPartName(modelService.getPurchaseName(item.getPartId()));
            item.setrCompanyName(modelService.getCompanyName(item.getrCompanyId()));
        }

        model.addAttribute("page", dataPage);
        model.addAttribute("PagePackage", PagePackage(dataPage.getPn(), dataPage.getStart(), dataPage.getPageSize(), dataPage.getTotalPages(), dataPage.getTotalItems()));
        model.addAttribute("dtoQuery", dtoQuery);

        //获取采购人
        modelService.getManagerPage(model);

        //供应商
        modelService.getCompayPage(model, 2);

        //region 显示标题
        String showTitle;
        switch (bxType) {
            case 2:
                showTitle = "采购";
                break;
            case 3:
                showTitle = "配件";
                break;
            default:
                showTitle = "未知";
                break;
        }
        model.addAttribute("showTitle", showTitle);
        //endregion

        return "erp/expense/index-expense";
    }
    //endregion

    //region 根据报销ID获取审批ID

    /**
     * 根据报销ID获取审批ID
     *
     * @param request servlet
     * @param bxId    报销ID
     * @return
     */
    @RequestMapping(value = "/getBxObj", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> getBxDTO(HttpServletRequest request, Integer bxId) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("returnCode", 0);

        if (bxId == null || bxId <= 0) {
            map.put("returnMessage", "未查询到报销信息");
            return map;
        }

        TransportExpenseDTO dto = expenseService.getById(bxId);
        if (dto == null) {
            map.put("returnMessage", "未查询到报销信息");
            return map;
        }

        map.put("id", dto.getApplyId());

        map.put("returnCode", 1);
        return map;
    }
    //endregion

}